home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
doom
/
ldhe-src.0
/
ldhe-src
/
dehacked
/
source
/
ttyobj.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-20
|
5KB
|
260 lines
// Nice to use C++ for object orientedness for once. ;)
//
// A class describing and giving access to a frame-buffered screen. :)
//
// -Sam Lantinga 3/18/95
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#if defined(HAVE_VGA) && defined(linux)
#include <linux/vt.h>
#endif
#include "dehacked.h"
#undef TEXT
#undef WIDTH
#undef HEIGHT
#include "ttyobj.h"
TTY::TTY(int lines, int cols) {
#if defined(HAVE_VGA) && defined(linux)
struct vt_stat stats;
#endif
int i, j;
#if defined(HAVE_VGA) && defined(linux)
// Figure out what kind of display we have.
if ( (geteuid() == 0) && (ioctl(2, VT_GETSTATE, &stats) == 0) ) {
// We're in a Linux console with VGA permissions.
graphics = new VGA_Graphics;
} else
#endif
if ( getenv("DISPLAY") != NULL ) {
// We're in an X11 display.
graphics = new X11_Graphics;
} else {
// Assume a vt100 window.
graphics = new TTY_Graphics;
}
keyboard = graphics->keyboard;
memory = new char*[lines];
for ( i=0; i<lines; ++i )
memory[i] = new char[cols*2];
maxy=lines; maxx=cols;
for ( i=0; i<maxy; ++i ) {
for ( j=0; j<maxx; ++j ) {
memory[i][j*2]=' ';
memory[i][(j*2)+1]=0;
}
}
oldx=oldy=curx=cury=0;
currattr=0;
}
TTY:: ~TTY()
{
delete graphics;
delete memory;
}
void
TTY:: moveto(int x, int y) {
// Check bounds..
if ( (x > maxx) || (y > maxy) ) {
moveto(maxx, maxy);
return;
}
// Move to new position.
oldx=curx;
oldy=cury;
curx=x-1;
cury=y-1;
graphics->gotoxy(x, y);
graphics->flush();
}
void
TTY:: curpos(int *x, int *y) {
*x=curx+1;
*y=cury+1;
}
void
TTY:: clear(void) {
TTY::attrib(0);
for ( int i=0; i<maxy; ++i ) {
for ( int j=0; j<maxx; ++j ) {
memory[i][j*2]=' ';
memory[i][(j*2)+1]=0;
}
}
graphics->clear();
graphics->flush();
}
void
TTY:: clrbox(int x, int y, int width, int height) {
// Check bounds..
assert((x > 0) && (x <= maxx));
assert((y > 0) && (y <= maxy));
for ( int i=y-1; (i<(y+height-1))&&(i<maxy); ++i ) {
for ( int j=x-1; (j<(x+width-1))&&(j<maxx); ++j ) {
memory[i][(j*2)] = ' ';
memory[i][(j*2)+1] = currattr;
}
}
graphics->clrbox(x, y, width, height);
graphics->flush();
}
void
TTY:: clreol(void) {
while ( curx < 80 )
memory[cury][(curx++)*2]=' ';
graphics->clreol();
graphics->flush();
}
void
TTY:: putch(char ch) {
memory[cury][curx*2]=ch;
memory[cury][(curx*2)+1]=currattr;
// Wrap and/or scroll. -- Uhhh, don't scroll.
if ( curx+1 == maxx ) {
if ( cury+1 < maxy ) {
++cury;
}
curx=0;
} else
++curx;
// Write, but don't flush.
graphics->putch(ch);
}
void
TTY:: flush(void) {
graphics->flush();
}
void
TTY:: attrib(int attr) {
#ifdef NO_COLOR
return;
#else
int bright=0, bg=0, fg=0;
if ( attr == currattr )
return;
switch (attr) {
case INFO: bright+=BRIGHT; fg+=WHITE; bg+=CYAN;
break;
case INFGRAY: fg+=WHITE; bg+=CYAN;
break;
case INFDGRAY: bright+=DIM; fg+=WHITE; bg+=CYAN;
break;
case ERROR: bright+=BRIGHT; fg+=WHITE; bg+=RED;
break;
case INPUT: bright+=BRIGHT; fg+=WHITE; bg+=GREEN;
break;
case INPDGRAY: bright+=DIM; fg+=WHITE; bg+=GREEN;
break;
case INPHILIT: fg+=MAGENTA; bg+=GREEN;
break;
case NGRAY: fg+=WHITE; bg+=BLUE;
break;
case NORMAL: bright+=BRIGHT; fg+=WHITE; bg+=BLUE;
break;
case NERROR: fg+=RED; bg+=BLUE;
break;
case NHILIT: fg+=BLUE; bg+=WHITE;
break;
default: currattr=0;
graphics->set_default_colors();
graphics->flush();
return;
}
currattr=((bright<<6)|(fg<<3)|bg);
graphics->set_colors(bright, fg, bg);
graphics->flush();
#endif
}
void
TTY:: highlight(int x, int y, int attr) {
// Check bounds..
assert(x <= maxx);
assert(y <= maxy);
TTY::attrib(attr);
memory[y-1][((x-1)*2)+1] = currattr;
graphics->gotoxy(x, y);
graphics->putch(memory[y-1][(x-1)*2]);
graphics->flush();
}
void
TTY:: gettext(int left, int top, int right, int bottom, char *buffer) {
for ( int i=top; i<=bottom && i<=maxy; ++i ) {
for ( int j=left; j<=right && j<=maxx; ++j ) {
*(buffer++)=memory[i-1][(j-1)*2];
*(buffer++)=memory[i-1][((j-1)*2)+1];
}
}
}
void
TTY:: puttext(int left, int top, int right, int bottom, char *buffer)
{
char attr=0, a, c;
int bright, fg, bg;
for ( int i=top; i<=bottom && i<=maxy; ++i ) {
graphics->gotoxy(left, i);
for ( int j=left; j<=right && j<=maxx; ++j ) {
c = *(buffer++);
memory[i-1][(j-1)*2] = c;
a = *(buffer++);
memory[i-1][((j-1)*2)+1] = a;
// Update the screen.
if ( a != attr ) {
bright = ((a>>6)&0x07);
fg = ((a>>3)&0x07);
bg = (a&0x07);
graphics->set_colors(bright, fg, bg);
attr=a;
}
graphics->putch(c);
}
}
graphics->flush();
}
void
TTY:: refresh(void)
{
char *screenbuf = new char[maxx*maxy*2];
gotoxy(1, 1);
gettext(1, 1, maxx, maxy, screenbuf);
puttext(1, 1, maxx, maxy, screenbuf);
delete[] screenbuf;
}
#ifdef NOT_FINISHED
void
TTY:: scroll(void) {
// Scroll lines...
for ( int i=1; i<maxy; ++i )
memcpy(memory[i-1], memory[i], (maxx+1)*2);
// Empty bottom line.
for ( int j=0; j<maxx; ++j ) {
memory[i-1][j*2]=' ';
memory[i-1][(j*2)+1]=0;
}
}
#endif